<template>
  <div></div>
</template>

<script>
  import * as THREE from 'three'
  import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
  import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min'

  export default {
    name: 'TwelveFive',
    data() {
      return {
        cube: null,                     // 立方体对象
        sphere: null,                   // 球体对象
        hemisphereLight: null,         // 半球光对象
        directionalLight: null,         // 平行光对象
        lightHelper: null,              // 平行光辅助类
      }
    },
    mounted() {
      this.initScene();
      this.initCamera();
      this.initRenderer();
      this.addCube();
      this.addPlane();
      this.addAxesHelper();
      this.addOrbitControls();
      this.addDirectionalLight();
      this.addHemisphereLight();
      this.animation();
      this.initControl();
      this.listen();
    },
    methods: {
      // 初始化场景
      initScene() {
        this.scene = new THREE.Scene();
      },
      // 初始化相机
      initCamera() {
        // 创建一个相机 视点
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        // 设置相机的位置
        // this.camera.position.set(-30, 40, 30);
        this.camera.position.set(-10, 16, 14);
        this.camera.lookAt(0, 0, 0);
      },
      // 初始化渲染器
      initRenderer() {
        // 创建一个渲染器
        this.renderer = new THREE.WebGLRenderer();
        // 设置渲染器尺寸
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.shadowMap.enabled = true;
        document.body.appendChild(this.renderer.domElement);
      },
      // 添加一个立方体
      addCube() {
        const cubeGeometry = new THREE.BoxGeometry(8, 8, 8);
        const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff2288 });
        this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        this.cube.position.set(0, 8, 0)
        this.cube.castShadow = true;
        this.scene.add(this.cube);
      },
      // 添加一个平面，用来接收阴影
      addPlane() {
        const planeGeometry = new THREE.PlaneGeometry(100, 100);
        const planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});
        const plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.set(15, 0, 0);
        plane.receiveShadow = true;
        this.scene.add(plane);
      },
      // 添加相机辅助器
      addCameraHelper() {
        const cameraHelper = new THREE.CameraHelper(this.directionalLight.shadow.camera);
        this.scene.add(cameraHelper);
      },
      // 添加世界坐标辅助器
      addAxesHelper() {
        const axesHelper = new THREE.AxesHelper(50);
        this.scene.add(axesHelper);
      },
      // 添加轨道控制器
      addOrbitControls() {
        this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
        // 设置带阻尼的惯性
        this.orbitControls.enableDamping = true;
        // 设置阻尼系数
        this.orbitControls.dampingFactor = 0.05;
      },
      // 添加平行光
      addDirectionalLight() {
        this.directionalLight = new THREE.DirectionalLight(0xFFFFFF, 4);
        this.directionalLight.position.set(30, 30, 30);
        this.directionalLight.castShadow = true;
        this.directionalLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
        this.scene.add(this.directionalLight);
      },
      // 添加半球光
      addHemisphereLight() {
        this.hemisphereLight = new THREE.HemisphereLight(0xFFFFFF, 0x00ff00, 1);
        this.scene.add( this.hemisphereLight );
      },
      // 动画函数
      animation() {
        this.orbitControls.update();
        // 渲染
        this.renderer.render(this.scene, this.camera);
        requestAnimationFrame(this.animation);
      },
      // 初始化lil.gui调试工具
      initControl() {
        const gui = new GUI();

        const params = {
          color: this.hemisphereLight.color,
          groundColor: this.hemisphereLight.groundColor,
          intensity: this.hemisphereLight.intensity,
          visible: this.hemisphereLight.visible,
        }

        let folder = gui.addFolder('半球光属性');
        folder.addColor(params, 'color').name('color-天空光线颜色').onChange(val => {
          this.hemisphereLight.color = val;
        })
        folder.addColor(params, 'groundColor').name('groundColor-地面光线颜色').onChange(val => {
          this.hemisphereLight.groundColor = val;
        })
        folder.add(params, 'intensity', 1, 10).step(0.1).name('intensity-强度').onChange(val => {
          this.hemisphereLight.intensity = val;
        })
        folder.add(params, 'visible').name('visible-是否显示').onChange(val => {
          this.hemisphereLight.visible = val;
        })
      },
      listen() {
        // 监听窗口变化
        window.addEventListener('resize', () => {
          // 重置渲染器宽高比
          this.renderer.setSize(window.innerWidth, window.innerHeight);
          // 重置相机宽高比
          this.camera.aspect = window.innerWidth / window.innerHeight;
          // 更新相机投影矩阵
          this.camera.updateProjectionMatrix();
        })
      }
    }
  }
</script>

<style scoped>

</style>
